#include "bindings/bindings_command_queue.h"
#include "helpers/general.h"
#include "models/renderer.h"
#include "rive/renderer/gl/render_buffer_gl_impl.hpp"
#include "rive/renderer/gl/render_context_gl_impl.hpp"
#include "rive/renderer/gl/render_target_gl.hpp"
#include "rive/renderer/rive_render_image.hpp"
#include <cstdint>
#include <EGL/egl.h>

#include <future>
#include <string>
/** Typedef for the below setProperty function. */
template <typename T>
using PropertySetter = void (rive::CommandQueue::*)(rive::ViewModelInstanceHandle, std::string, T, uint64_t);

/** Typedef for the below getProperty function. */
using PropertyGetter = void (rive::CommandQueue::*)(rive::ViewModelInstanceHandle, std::string, uint64_t);
namespace ohos_rive {

/** A generic setter for all property types. */
template <typename T>
void setProperty(napi_env env,
                 int64_t ref,
                 int64_t jViewModelInstanceHandle,
                 const char *propertyPath,
                 T value,
                 PropertySetter<T> setter)
{
    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto viewModelInstanceHandle = handleFromLong<rive::ViewModelInstanceHandle>(jViewModelInstanceHandle);

    (commandQueue->*setter)(viewModelInstanceHandle, propertyPath, value,
                            0); // Pass 0 for requestID
}

/** A generic getter for all property types. */
void getProperty(napi_env env,
                 int64_t ref,
                 int64_t requestID,
                 int64_t jViewModelInstanceHandle,
                 const char *propertyPath,
                 PropertyGetter getter)
{
    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto viewModelInstanceHandle = handleFromLong<rive::ViewModelInstanceHandle>(jViewModelInstanceHandle);

    (commandQueue->*getter)(viewModelInstanceHandle, propertyPath, requestID);
}

/** Create a 1x1 PBuffer surface to bind before Android provides a surface. */
EGLSurface createPBufferSurface(EGLDisplay eglDisplay, EGLContext eglContext)
{
    EGLint configID = 0;
    eglQueryContext(eglDisplay, eglContext, EGL_CONFIG_ID, &configID);

    EGLConfig config;
    EGLint configCount = 0;
    EGLint configAttributes[] = {EGL_CONFIG_ID, configID, EGL_NONE};
    eglChooseConfig(eglDisplay, configAttributes, &config, 1, &configCount);

    // We expect only one config.
    if (configCount == 1) {
        EGLint pBufferAttributes[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE};
        return eglCreatePbufferSurface(eglDisplay, config, pBufferAttributes);
    } else {
        LOGE("Failed to choose EGL config for PBuffer surface");
        return EGL_NO_SURFACE;
    }
}

napi_value CommandQueueGetEglDisplay(napi_env env, napi_callback_info info)
{
    EGLDisplay display;
    EGLint majorVersion;
    EGLint minorVersion;
    display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    eglInitialize(display, &majorVersion, &minorVersion);

    auto displayPtr = reinterpret_cast<int64_t>(display);
    napi_value result;
    napi_create_int64(env, displayPtr, &result);
    return result;
}

napi_value CommandQueueCreateEglContext(napi_env env, napi_callback_info info)
{
    size_t argc = 1;
    napi_value args[1];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    if (argc < 1) {
        LOGE("Wrong number of arguments in CommandQueueCreateEglContext");
        return nullptr;
    }
    int64_t display;
    napi_get_value_int64(env, args[0], &display);

    auto eglDisplay = reinterpret_cast<EGLDisplay>(display);
    EGLConfig config;
    EGLContext context;
    EGLint attribs[] = {
        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_NONE};
    EGLint numConfigs = 0;
    eglChooseConfig(eglDisplay, attribs, &config, 1, &numConfigs);
    context = eglCreateContext(eglDisplay, config, EGL_NO_CONTEXT, NULL);

    auto contextPtr = reinterpret_cast<int64_t>(context);
    napi_value result;
    napi_create_int64(env, contextPtr, &result);
    return result;
}

napi_value CommandQueueDeleteEglContext(napi_env env, napi_callback_info info)
{
    size_t argc = 2;
    napi_value args[2];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    if (argc < 2) {
        LOGE("Wrong number of arguments in CommandQueueDeleteEglContext");
        return nullptr;
    }
    int64_t display;
    napi_get_value_int64(env, args[0], &display);
    int64_t context;
    napi_get_value_int64(env, args[1], &context);

    auto eglDisplay = reinterpret_cast<EGLDisplay>(display);
    auto eglContext = reinterpret_cast<EGLContext>(context);
    eglDestroyContext(eglDisplay, eglContext);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

napi_value CommandQueueCreateEglSurface(napi_env env, napi_callback_info info)
{
    size_t argc = 2;
    napi_value args[2];
    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
    if (argc < 2) {
        LOGE("Wrong number of arguments in CommandQueueCreateEglSurface");
        return nullptr;
    }
    int64_t display;
    napi_get_value_int64(env, args[0], &display);
    int64_t context;
    napi_get_value_int64(env, args[1], &context);

    auto eglDisplay = reinterpret_cast<EGLDisplay>(display);
    auto eglContext = reinterpret_cast<EGLContext>(context);

    EGLSurface surface = createPBufferSurface(eglDisplay, eglContext);

    napi_value result;
    napi_create_int64(env, longFromHandle(surface), &result);
    return result;
}

/**
 * CommandQueue 构造函数
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppConstructor
 */
napi_value CommandQueueConstructor(napi_env env, napi_callback_info info)
{
    size_t argc = 2;
    napi_value args[2];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 2) {
        LOGE("Wrong number of arguments in CommandQueueConstructor");
        return nullptr;
    }

    // 获取 display 和 context 参数
    int64_t display, context;
    napi_get_value_int64(env, args[0], &display);
    napi_get_value_int64(env, args[1], &context);

    auto eglDisplay = reinterpret_cast<EGLDisplay>(display);
    auto eglContext = reinterpret_cast<EGLContext>(context);

    auto commandQueue = rive::rcp<rive::CommandQueue>(new rive::CommandQueue());

    struct StartupResult {
        bool success;
        EGLint eglError;
        std::string message;
    };

    // Used by the CommandServer thread to signal startup success or failure
    std::promise<StartupResult> promise;
    // Blocks the main thread until the CommandServer is ready
    std::future<StartupResult> f = promise.get_future();

    // Setup the C++ thread that drives the CommandServer
    std::thread([eglDisplay, eglContext, commandQueue, promise = std::move(promise)]() mutable {
        auto pBuffer = createPBufferSurface(eglDisplay, eglContext);
        if (pBuffer == EGL_NO_SURFACE) {
            auto error = eglGetError();
            LOGE("Failed to create PBuffer surface. Error: (0x%04x)", error);
            promise.set_value({false, error, "Failed to create PBuffer surface"});
            return;
        }

        auto contextCurrentSuccess = eglMakeCurrent(eglDisplay, pBuffer, pBuffer, eglContext);
        if (!contextCurrentSuccess) {
            auto error = eglGetError();
            LOGE("Failed to make EGL context current. Error: (0x%04x)", error);
            promise.set_value({false, error, "Failed to make EGL context current"});
            eglDestroySurface(eglDisplay, pBuffer);
            return;
        }

        auto riveContext = rive::gpu::RenderContextGLImpl::MakeContext();
        if (!riveContext) {
            auto error = eglGetError();
            LOGE("Failed to create Rive RenderContextGL. Error: (0x%04x)", error);
            promise.set_value({false, error, "Failed to create Rive RenderContextGL"});
            eglDestroySurface(eglDisplay, pBuffer);
            return;
        }

        auto commandServer = std::make_unique<rive::CommandServer>(commandQueue, riveContext.get());
        // Signal success and unblock the main thread
        promise.set_value({true, EGL_SUCCESS, "Command Server started successfully"});

        // Begin the serving loop. This will "block" the thread until the
        // server receives the disconnect command.
        commandServer->serveUntilDisconnect();
        // Matching unref from constructor since we release()'d.
        // Ensures the command queue outlives the command server's run.
        commandQueue->unref();

        // Cleanup the EGL context and surface
        eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        eglDestroySurface(eglDisplay, pBuffer);
    }).detach();

    // Wait for the command server to start and return the result
    auto result = f.get();
    if (!result.success) {
        char messageBuffer[256];
        snprintf(messageBuffer, sizeof(messageBuffer), "CommandQueue startup failed (EGL 0x%04x): %s", result.eglError,
                 result.message.c_str());
        LOGE("CommandQueue startup failed");
        return nullptr;
    }

    napi_value resultValue;
    napi_create_int64(env, reinterpret_cast<int64_t>(commandQueue.release()), &resultValue);
    return resultValue;
}

/**
 * CommandQueue 析构函数
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppDelete
 */
napi_value CommandQueueDelete(napi_env env, napi_callback_info info)
{
    size_t argc = 1;
    napi_value args[1];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 1) {
        LOGE("Wrong number of arguments in CommandQueueDelete");
        return nullptr;
    }

    int64_t ref;
    napi_get_value_int64(env, args[0], &ref);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    commandQueue->disconnect();

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 创建监听器
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppCreateListeners
 */
napi_value CommandQueueCreateListeners(napi_env env, napi_callback_info info)
{
    size_t argc = 2;
    napi_value args[2];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 2) {
        LOGE("Wrong number of arguments in CommandQueueCreateListeners");
        return nullptr;
    }

    int64_t ref;
    napi_get_value_int64(env, args[0], &ref);
    napi_value jsCommandQueue = args[1];

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);

    auto fileListener = new FileListener(env, jsCommandQueue);
    auto artboardListener = new ArtboardListener(env, jsCommandQueue);
    auto stateMachineListener = new StateMachineListener(env, jsCommandQueue);
    auto viewModelInstanceListener = new ViewModelInstanceListener(env, jsCommandQueue);
    auto imageListener = new ImageListener(env, jsCommandQueue);
    auto audioListener = new AudioListener(env, jsCommandQueue);
    auto fontListener = new FontListener(env, jsCommandQueue);

    commandQueue->setGlobalFileListener(fileListener);
    commandQueue->setGlobalArtboardListener(artboardListener);
    commandQueue->setGlobalStateMachineListener(stateMachineListener);
    commandQueue->setGlobalViewModelInstanceListener(viewModelInstanceListener);
    commandQueue->setGlobalRenderImageListener(imageListener);
    commandQueue->setGlobalAudioSourceListener(audioListener);
    commandQueue->setGlobalFontListener(fontListener);

    napi_value result;
    napi_create_object(env, &result);

    napi_value fileListenerValue, artboardListenerValue, stateMachineListenerValue;
    napi_value viewModelInstanceListenerValue, imageListenerValue, audioListenerValue, fontListenerValue;

    napi_create_int64(env, reinterpret_cast<int64_t>(fileListener), &fileListenerValue);
    napi_create_int64(env, reinterpret_cast<int64_t>(artboardListener), &artboardListenerValue);
    napi_create_int64(env, reinterpret_cast<int64_t>(stateMachineListener), &stateMachineListenerValue);
    napi_create_int64(env, reinterpret_cast<int64_t>(viewModelInstanceListener), &viewModelInstanceListenerValue);
    napi_create_int64(env, reinterpret_cast<int64_t>(imageListener), &imageListenerValue);
    napi_create_int64(env, reinterpret_cast<int64_t>(audioListener), &audioListenerValue);
    napi_create_int64(env, reinterpret_cast<int64_t>(fontListener), &fontListenerValue);

    napi_set_named_property(env, result, "fileListener", fileListenerValue);
    napi_set_named_property(env, result, "artboardListener", artboardListenerValue);
    napi_set_named_property(env, result, "stateMachineListener", stateMachineListenerValue);
    napi_set_named_property(env, result, "viewModelInstanceListener", viewModelInstanceListenerValue);
    napi_set_named_property(env, result, "imageListener", imageListenerValue);
    napi_set_named_property(env, result, "audioListener", audioListenerValue);
    napi_set_named_property(env, result, "fontListener", fontListenerValue);

    return result;
}

/**
 * CommandQueue 创建渲染目标
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppCreateRenderTarget
 */
napi_value CommandQueueCreateRenderTarget(napi_env env, napi_callback_info info)
{
    size_t argc = 2;
    napi_value args[2];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 2) {
        LOGE("Wrong number of arguments in CommandQueueCreateRenderTarget");
        return nullptr;
    }

    int32_t width, height;
    napi_get_value_int32(env, args[0], &width);
    napi_get_value_int32(env, args[1], &height);

    GLint sampleCount;
    glGetIntegerv(GL_SAMPLES, &sampleCount);

    auto renderTarget = new rive::gpu::FramebufferRenderTargetGL(width, height, 0, sampleCount);

    napi_value result;
    napi_create_int64(env, reinterpret_cast<int64_t>(renderTarget), &result);
    return result;
}

/**
 * CommandQueue 加载文件
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppLoadFile
 */
napi_value CommandQueueLoadFile(napi_env env, napi_callback_info info)
{
    size_t argc = 3;
    napi_value args[3];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 3) {
        LOGE("Wrong number of arguments in CommandQueueLoadFile");
        return nullptr;
    }

    int64_t ref, requestID;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);

    void *arrayBufferData;
    size_t arrayBufferLength;
    napi_get_arraybuffer_info(env, args[2], &arrayBufferData, &arrayBufferLength);

    std::vector<uint8_t> byteVec(static_cast<uint8_t *>(arrayBufferData),
                                 static_cast<uint8_t *>(arrayBufferData) + arrayBufferLength);

    auto fileHandle = commandQueue->loadFile(byteVec, nullptr, requestID);
    auto fileHandlePtr = reinterpret_cast<int64_t>(fileHandle);
    napi_value result;
    napi_create_int64(env, fileHandlePtr, &result);
    return result;
}

/**
 * CommandQueue 删除文件
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppDeleteFile
 */
napi_value CommandQueueDeleteFile(napi_env env, napi_callback_info info)
{
    size_t argc = 3;
    napi_value args[3];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 3) {
        LOGE("Wrong number of arguments in CommandQueueDeleteFile");
        return nullptr;
    }

    int64_t ref, requestID, fileHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &fileHandle);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    commandQueue->deleteFile(handleFromLong<rive::FileHandle>(fileHandle), requestID);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 获取画板名称
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppGetArtboardNames
 */
napi_value CommandQueueGetArtboardNames(napi_env env, napi_callback_info info)
{
    size_t argc = 3;
    napi_value args[3];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 3) {
        LOGE("Wrong number of arguments in CommandQueueGetArtboardNames");
        return nullptr;
    }

    int64_t ref, requestID, fileHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &fileHandle);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto handle = handleFromLong<rive::FileHandle>(fileHandle);
    commandQueue->requestArtboardNames(handle, requestID);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 获取状态机名称
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppGetStateMachineNames
 */
napi_value CommandQueueGetStateMachineNames(napi_env env, napi_callback_info info)
{
    size_t argc = 3;
    napi_value args[3];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 3) {
        LOGE("Wrong number of arguments in CommandQueueGetStateMachineNames");
        return nullptr;
    }

    int64_t ref, requestID, artboardHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &artboardHandle);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto handle = handleFromLong<rive::ArtboardHandle>(artboardHandle);
    commandQueue->requestStateMachineNames(handle, requestID);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 获取视图模型名称
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppGetViewModelNames
 */
napi_value CommandQueueGetViewModelNames(napi_env env, napi_callback_info info)
{
    size_t argc = 3;
    napi_value args[3];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 3) {
        LOGE("Wrong number of arguments in CommandQueueGetViewModelNames");
        return nullptr;
    }

    int64_t ref, requestID, fileHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &fileHandle);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto handle = handleFromLong<rive::FileHandle>(fileHandle);
    commandQueue->requestViewModelNames(handle, requestID);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 获取视图模型实例名称
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppGetViewModelInstanceNames
 */
napi_value CommandQueueGetViewModelInstanceNames(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueGetViewModelInstanceNames");
        return nullptr;
    }

    int64_t ref, requestID, fileHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &fileHandle);

    size_t viewModelNameLength;
    napi_get_value_string_utf8(env, args[3], nullptr, 0, &viewModelNameLength);
    std::string viewModelName(viewModelNameLength + 1, '\0');
    napi_get_value_string_utf8(env, args[3], &viewModelName[0], viewModelNameLength + 1, &viewModelNameLength);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto handle = handleFromLong<rive::FileHandle>(fileHandle);
    commandQueue->requestViewModelInstanceNames(handle, viewModelName, requestID);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 获取视图模型属性
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppGetViewModelProperties
 */
napi_value CommandQueueGetViewModelProperties(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueGetViewModelProperties");
        return nullptr;
    }

    int64_t ref, requestID, fileHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &fileHandle);

    size_t viewModelNameLength;
    napi_get_value_string_utf8(env, args[3], nullptr, 0, &viewModelNameLength);
    std::string viewModelName(viewModelNameLength + 1, '\0');
    napi_get_value_string_utf8(env, args[3], &viewModelName[0], viewModelNameLength + 1, &viewModelNameLength);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto handle = handleFromLong<rive::FileHandle>(fileHandle);
    commandQueue->requestViewModelPropertyDefinitions(handle, viewModelName, requestID);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 获取枚举
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppGetEnums
 */
napi_value CommandQueueGetEnums(napi_env env, napi_callback_info info)
{
    size_t argc = 3;
    napi_value args[3];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 3) {
        LOGE("Wrong number of arguments in CommandQueueGetEnums");
        return nullptr;
    }

    int64_t ref, requestID, fileHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &fileHandle);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto handle = handleFromLong<rive::FileHandle>(fileHandle);
    commandQueue->requestViewModelEnums(handle, requestID);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 创建默认画板
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppCreateDefaultArtboard
 */
napi_value CommandQueueCreateDefaultArtboard(napi_env env, napi_callback_info info)
{
    size_t argc = 3;
    napi_value args[3];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 3) {
        LOGE("Wrong number of arguments in CommandQueueCreateDefaultArtboard");
        return nullptr;
    }

    int64_t ref, requestID, fileHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &fileHandle);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto artboard =
        commandQueue->instantiateDefaultArtboard(handleFromLong<rive::FileHandle>(fileHandle), nullptr, requestID);

    napi_value result;
    napi_create_int64(env, longFromHandle(artboard), &result);
    return result;
}

/**
 * CommandQueue 按名称创建画板
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppCreateArtboardByName
 */
napi_value CommandQueueCreateArtboardByName(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueCreateArtboardByName");
        return nullptr;
    }

    int64_t ref, requestID, fileHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &fileHandle);

    size_t nameLength;
    napi_get_value_string_utf8(env, args[3], nullptr, 0, &nameLength);
    std::string name(nameLength + 1, '\0');
    napi_get_value_string_utf8(env, args[3], &name[0], nameLength + 1, &nameLength);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto artboard =
        commandQueue->instantiateArtboardNamed(handleFromLong<rive::FileHandle>(fileHandle), name, nullptr, requestID);

    napi_value result;
    napi_create_int64(env, longFromHandle(artboard), &result);
    return result;
}

/**
 * CommandQueue 删除画板
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppDeleteArtboard
 */
napi_value CommandQueueDeleteArtboard(napi_env env, napi_callback_info info)
{
    size_t argc = 3;
    napi_value args[3];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 3) {
        LOGE("Wrong number of arguments in CommandQueueDeleteArtboard");
        return nullptr;
    }

    int64_t ref, requestID, artboardHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &artboardHandle);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    commandQueue->deleteArtboard(handleFromLong<rive::ArtboardHandle>(artboardHandle), requestID);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 创建状态机
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppCreateDefaultStateMachine
 */
napi_value CommandQueueCreateDefaultStateMachine(napi_env env, napi_callback_info info)
{
    size_t argc = 3;
    napi_value args[3];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 3) {
        LOGE("Wrong number of arguments in CommandQueueCreateDefaultStateMachine");
        return nullptr;
    }

    int64_t ref, requestID, artboardHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &artboardHandle);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto stateMachine = commandQueue->instantiateDefaultStateMachine(
        handleFromLong<rive::ArtboardHandle>(artboardHandle), nullptr, requestID);

    napi_value result;
    napi_create_int64(env, longFromHandle(stateMachine), &result);
    return result;
}

/**
 * CommandQueue 按名称创建状态机
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppCreateStateMachineByName
 */
napi_value CommandQueueCreateStateMachineByName(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueCreateStateMachineByName");
        return nullptr;
    }

    int64_t ref, requestID, artboardHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &artboardHandle);

    size_t nameLength;
    napi_get_value_string_utf8(env, args[3], nullptr, 0, &nameLength);
    std::string name(nameLength + 1, '\0');
    napi_get_value_string_utf8(env, args[3], &name[0], nameLength + 1, &nameLength);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto stateMachine = commandQueue->instantiateStateMachineNamed(handleFromLong<rive::ArtboardHandle>(artboardHandle),
                                                                   name, nullptr, requestID);

    napi_value result;
    napi_create_int64(env, longFromHandle(stateMachine), &result);
    return result;
}

/**
 * CommandQueue 删除状态机
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppDeleteStateMachine
 */
napi_value CommandQueueDeleteStateMachine(napi_env env, napi_callback_info info)
{
    size_t argc = 3;
    napi_value args[3];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 3) {
        LOGE("Wrong number of arguments in CommandQueueDeleteStateMachine");
        return nullptr;
    }

    int64_t ref, requestID, stateMachineHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &stateMachineHandle);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    commandQueue->deleteStateMachine(handleFromLong<rive::StateMachineHandle>(stateMachineHandle), requestID);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 推进状态机
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppAdvanceStateMachine
 */
napi_value CommandQueueAdvanceStateMachine(napi_env env, napi_callback_info info)
{
    size_t argc = 3;
    napi_value args[3];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 3) {
        LOGE("Wrong number of arguments in CommandQueueAdvanceStateMachine");
        return nullptr;
    }

    int64_t ref, stateMachineHandle, deltaTimeNs;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &stateMachineHandle);
    napi_get_value_int64(env, args[2], &deltaTimeNs);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto deltaSeconds = static_cast<float_t>(deltaTimeNs) / 1e9f; // NS to S
    commandQueue->advanceStateMachine(handleFromLong<rive::StateMachineHandle>(stateMachineHandle), deltaSeconds);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 按视图模型名称创建空白视图模型实例
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppNamedVMCreateBlankVMI
 */
napi_value CommandQueueNamedVMCreateBlankVMI(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueNamedVMCreateBlankVMI");
        return nullptr;
    }

    int64_t ref, requestID, fileHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &fileHandle);

    size_t viewModelNameLength;
    napi_get_value_string_utf8(env, args[3], nullptr, 0, &viewModelNameLength);
    std::string viewModelName(viewModelNameLength + 1, '\0');
    napi_get_value_string_utf8(env, args[3], &viewModelName[0], viewModelNameLength + 1, &viewModelNameLength);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto handle = handleFromLong<rive::FileHandle>(fileHandle);
    auto viewModelInstance = commandQueue->instantiateBlankViewModelInstance(handle, viewModelName, nullptr, requestID);

    napi_value result;
    napi_create_int64(env, longFromHandle(viewModelInstance), &result);
    return result;
}

/**
 * CommandQueue 按默认视图模型创建空白视图模型实例
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppDefaultVMCreateBlankVMI
 */
napi_value CommandQueueDefaultVMCreateBlankVMI(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueDefaultVMCreateBlankVMI");
        return nullptr;
    }

    int64_t ref, requestID, fileHandle, artboardHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &fileHandle);
    napi_get_value_int64(env, args[3], &artboardHandle);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto longFileHandle = handleFromLong<rive::FileHandle>(fileHandle);
    auto longArtboardHandle = handleFromLong<rive::ArtboardHandle>(artboardHandle);
    auto viewModelInstance =
        commandQueue->instantiateBlankViewModelInstance(longFileHandle, longArtboardHandle, nullptr, requestID);

    napi_value result;
    napi_create_int64(env, longFromHandle(viewModelInstance), &result);
    return result;
}

/**
 * CommandQueue 按视图模型名称创建默认视图模型实例
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppNamedVMCreateDefaultVMI
 */
napi_value CommandQueueNamedVMCreateDefaultVMI(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueNamedVMCreateDefaultVMI");
        return nullptr;
    }

    int64_t ref, requestID, fileHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &fileHandle);

    size_t viewModelNameLength;
    napi_get_value_string_utf8(env, args[3], nullptr, 0, &viewModelNameLength);
    std::string viewModelName(viewModelNameLength + 1, '\0');
    napi_get_value_string_utf8(env, args[3], &viewModelName[0], viewModelNameLength + 1, &viewModelNameLength);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto handle = handleFromLong<rive::FileHandle>(fileHandle);
    auto viewModelInstance =
        commandQueue->instantiateDefaultViewModelInstance(handle, viewModelName, nullptr, requestID);

    napi_value result;
    napi_create_int64(env, longFromHandle(viewModelInstance), &result);
    return result;
}

/**
 * CommandQueue 按默认视图模型创建默认视图模型实例
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppDefaultVMCreateDefaultVMI
 */
napi_value CommandQueueDefaultVMCreateDefaultVMI(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueDefaultVMCreateDefaultVMI");
        return nullptr;
    }

    int64_t ref, requestID, fileHandle, artboardHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &fileHandle);
    napi_get_value_int64(env, args[3], &artboardHandle);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto longFileHandle = handleFromLong<rive::FileHandle>(fileHandle);
    auto longArtboardHandle = handleFromLong<rive::ArtboardHandle>(artboardHandle);
    auto viewModelInstance =
        commandQueue->instantiateDefaultViewModelInstance(longFileHandle, longArtboardHandle, nullptr, requestID);

    napi_value result;
    napi_create_int64(env, longFromHandle(viewModelInstance), &result);
    return result;
}

/**
 * CommandQueue 按视图模型名称和实例名称创建视图模型实例
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppNamedVMCreateNamedVMI
 */
napi_value CommandQueueNamedVMCreateNamedVMI(napi_env env, napi_callback_info info)
{
    size_t argc = 5;
    napi_value args[5];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 5) {
        LOGE("Wrong number of arguments in CommandQueueNamedVMCreateNamedVMI");
        return nullptr;
    }

    int64_t ref, requestID, fileHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &fileHandle);

    size_t viewModelNameLength, instanceNameLength;
    napi_get_value_string_utf8(env, args[3], nullptr, 0, &viewModelNameLength);
    napi_get_value_string_utf8(env, args[4], nullptr, 0, &instanceNameLength);

    std::string viewModelName(viewModelNameLength + 1, '\0');
    std::string instanceName(instanceNameLength + 1, '\0');
    napi_get_value_string_utf8(env, args[3], &viewModelName[0], viewModelNameLength + 1, &viewModelNameLength);
    napi_get_value_string_utf8(env, args[4], &instanceName[0], instanceNameLength + 1, &instanceNameLength);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto handle = handleFromLong<rive::FileHandle>(fileHandle);
    auto viewModelInstance =
        commandQueue->instantiateViewModelInstanceNamed(handle, viewModelName, instanceName, nullptr, requestID);

    napi_value result;
    napi_create_int64(env, longFromHandle(viewModelInstance), &result);
    return result;
}

/**
 * CommandQueue 按默认视图模型和实例名称创建视图模型实例
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppDefaultVMCreateNamedVMI
 */
napi_value CommandQueueDefaultVMCreateNamedVMI(napi_env env, napi_callback_info info)
{
    size_t argc = 5;
    napi_value args[5];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 5) {
        LOGE("Wrong number of arguments in CommandQueueDefaultVMCreateNamedVMI");
        return nullptr;
    }

    int64_t ref, requestID, fileHandle, artboardHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &fileHandle);
    napi_get_value_int64(env, args[3], &artboardHandle);

    size_t instanceNameLength;
    napi_get_value_string_utf8(env, args[4], nullptr, 0, &instanceNameLength);
    std::string instanceName(instanceNameLength + 1, '\0');
    napi_get_value_string_utf8(env, args[4], &instanceName[0], instanceNameLength + 1, &instanceNameLength);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto longFileHandle = handleFromLong<rive::FileHandle>(fileHandle);
    auto longArtboardHandle = handleFromLong<rive::ArtboardHandle>(artboardHandle);
    auto viewModelInstance = commandQueue->instantiateViewModelInstanceNamed(longFileHandle, longArtboardHandle,
                                                                             instanceName, nullptr, requestID);

    napi_value result;
    napi_create_int64(env, longFromHandle(viewModelInstance), &result);
    return result;
}

/**
 * CommandQueue 引用嵌套视图模型实例
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppReferenceNestedVMI
 */
napi_value CommandQueueReferenceNestedVMI(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueReferenceNestedVMI");
        return nullptr;
    }

    int64_t ref, requestID, viewModelInstanceHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &viewModelInstanceHandle);

    size_t pathLength;
    napi_get_value_string_utf8(env, args[3], nullptr, 0, &pathLength);
    std::string path(pathLength + 1, '\0');
    napi_get_value_string_utf8(env, args[3], &path[0], pathLength + 1, &pathLength);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto handle = handleFromLong<rive::ViewModelInstanceHandle>(viewModelInstanceHandle);
    auto nestedViewModelInstance = commandQueue->referenceNestedViewModelInstance(handle, path, nullptr, requestID);

    napi_value result;
    napi_create_int64(env, longFromHandle(nestedViewModelInstance), &result);
    return result;
}

/**
 * CommandQueue 删除视图模型实例
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppDeleteViewModelInstance
 */
napi_value CommandQueueDeleteViewModelInstance(napi_env env, napi_callback_info info)
{
    size_t argc = 3;
    napi_value args[3];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 3) {
        LOGE("Wrong number of arguments in CommandQueueDeleteViewModelInstance");
        return nullptr;
    }

    int64_t ref, requestID, viewModelInstanceHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &viewModelInstanceHandle);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto handle = handleFromLong<rive::ViewModelInstanceHandle>(viewModelInstanceHandle);
    commandQueue->deleteViewModelInstance(handle, requestID);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 绑定视图模型实例
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppBindViewModelInstance
 */
napi_value CommandQueueBindViewModelInstance(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueBindViewModelInstance");
        return nullptr;
    }

    int64_t ref, requestID, stateMachineHandle, viewModelInstanceHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &stateMachineHandle);
    napi_get_value_int64(env, args[3], &viewModelInstanceHandle);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto StateMachineHandle = handleFromLong<rive::StateMachineHandle>(stateMachineHandle);
    auto ViewModelInstanceHandle = handleFromLong<rive::ViewModelInstanceHandle>(viewModelInstanceHandle);
    commandQueue->bindViewModelInstance(StateMachineHandle, ViewModelInstanceHandle, requestID);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 设置数字属性
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppSetNumberProperty
 */
napi_value CommandQueueSetNumberProperty(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueSetNumberProperty");
        return nullptr;
    }

    int64_t ref, viewModelInstanceHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &viewModelInstanceHandle);

    size_t pathLength;
    napi_get_value_string_utf8(env, args[2], nullptr, 0, &pathLength);
    std::string propertyPath(pathLength + 1, '\0');
    napi_get_value_string_utf8(env, args[2], &propertyPath[0], pathLength + 1, &pathLength);

    double value;
    napi_get_value_double(env, args[3], &value);

    setProperty(env, ref, viewModelInstanceHandle, propertyPath.c_str(), static_cast<float>(value),
                &rive::CommandQueue::setViewModelInstanceNumber);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 获取数字属性
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppGetNumberProperty
 */
napi_value CommandQueueGetNumberProperty(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueGetNumberProperty");
        return nullptr;
    }

    int64_t ref, requestID, viewModelInstanceHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &viewModelInstanceHandle);

    size_t pathLength;
    napi_get_value_string_utf8(env, args[3], nullptr, 0, &pathLength);
    std::string propertyPath(pathLength + 1, '\0');
    napi_get_value_string_utf8(env, args[3], &propertyPath[0], pathLength + 1, &pathLength);

    getProperty(env, ref, requestID, viewModelInstanceHandle, propertyPath.c_str(),
                &rive::CommandQueue::requestViewModelInstanceNumber);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 设置字符串属性
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppSetStringProperty
 */
napi_value CommandQueueSetStringProperty(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueSetStringProperty");
        return nullptr;
    }

    int64_t ref, viewModelInstanceHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &viewModelInstanceHandle);

    size_t pathLength, valueLength;
    napi_get_value_string_utf8(env, args[2], nullptr, 0, &pathLength);
    napi_get_value_string_utf8(env, args[3], nullptr, 0, &valueLength);

    std::string propertyPath(pathLength + 1, '\0');
    std::string value(valueLength + 1, '\0');
    napi_get_value_string_utf8(env, args[2], &propertyPath[0], pathLength + 1, &pathLength);
    napi_get_value_string_utf8(env, args[3], &value[0], valueLength + 1, &valueLength);

    setProperty(env, ref, viewModelInstanceHandle, propertyPath.c_str(), value,
                &rive::CommandQueue::setViewModelInstanceString);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 获取字符串属性
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppGetStringProperty
 */
napi_value CommandQueueGetStringProperty(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueGetStringProperty");
        return nullptr;
    }

    int64_t ref, requestID, viewModelInstanceHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &viewModelInstanceHandle);

    size_t pathLength;
    napi_get_value_string_utf8(env, args[3], nullptr, 0, &pathLength);
    std::string propertyPath(pathLength + 1, '\0');
    napi_get_value_string_utf8(env, args[3], &propertyPath[0], pathLength + 1, &pathLength);

    getProperty(env, ref, requestID, viewModelInstanceHandle, propertyPath.c_str(),
                &rive::CommandQueue::requestViewModelInstanceString);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 设置布尔属性
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppSetBooleanProperty
 */
napi_value CommandQueueSetBooleanProperty(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueSetBooleanProperty");
        return nullptr;
    }

    int64_t ref, viewModelInstanceHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &viewModelInstanceHandle);

    size_t pathLength;
    napi_get_value_string_utf8(env, args[2], nullptr, 0, &pathLength);
    std::string propertyPath(pathLength + 1, '\0');
    napi_get_value_string_utf8(env, args[2], &propertyPath[0], pathLength + 1, &pathLength);

    bool value;
    napi_get_value_bool(env, args[3], &value);

    setProperty<bool>(env, ref, viewModelInstanceHandle, propertyPath.c_str(), value,
                      &rive::CommandQueue::setViewModelInstanceBool);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 获取布尔属性
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppGetBooleanProperty
 */
napi_value CommandQueueGetBooleanProperty(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueGetBooleanProperty");
        return nullptr;
    }

    int64_t ref, requestID, viewModelInstanceHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &viewModelInstanceHandle);

    size_t pathLength;
    napi_get_value_string_utf8(env, args[3], nullptr, 0, &pathLength);
    std::string propertyPath(pathLength + 1, '\0');
    napi_get_value_string_utf8(env, args[3], &propertyPath[0], pathLength + 1, &pathLength);

    getProperty(env, ref, requestID, viewModelInstanceHandle, propertyPath.c_str(),
                &rive::CommandQueue::requestViewModelInstanceBool);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 设置枚举属性
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppSetEnumProperty
 */
napi_value CommandQueueSetEnumProperty(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueSetEnumProperty");
        return nullptr;
    }

    int64_t ref, viewModelInstanceHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &viewModelInstanceHandle);

    size_t pathLength, valueLength;
    napi_get_value_string_utf8(env, args[2], nullptr, 0, &pathLength);
    napi_get_value_string_utf8(env, args[3], nullptr, 0, &valueLength);

    std::string propertyPath(pathLength + 1, '\0');
    std::string value(valueLength + 1, '\0');
    napi_get_value_string_utf8(env, args[2], &propertyPath[0], pathLength + 1, &pathLength);
    napi_get_value_string_utf8(env, args[3], &value[0], valueLength + 1, &valueLength);

    setProperty(env, ref, viewModelInstanceHandle, propertyPath.c_str(), value,
                &rive::CommandQueue::setViewModelInstanceEnum);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 获取枚举属性
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppGetEnumProperty
 */
napi_value CommandQueueGetEnumProperty(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueGetEnumProperty");
        return nullptr;
    }

    int64_t ref, requestID, viewModelInstanceHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &viewModelInstanceHandle);

    size_t pathLength;
    napi_get_value_string_utf8(env, args[3], nullptr, 0, &pathLength);
    std::string propertyPath(pathLength + 1, '\0');
    napi_get_value_string_utf8(env, args[3], &propertyPath[0], pathLength + 1, &pathLength);

    getProperty(env, ref, requestID, viewModelInstanceHandle, propertyPath.c_str(),
                &rive::CommandQueue::requestViewModelInstanceEnum);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 颜色属性设置
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppSetColorProperty
 */
napi_value CommandQueueSetColorProperty(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueSetColorProperty");
        return nullptr;
    }

    int64_t ref, viewModelInstanceHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &viewModelInstanceHandle);

    size_t pathLength;
    napi_get_value_string_utf8(env, args[2], nullptr, 0, &pathLength);
    std::string propertyPath(pathLength + 1, '\0');
    napi_get_value_string_utf8(env, args[2], &propertyPath[0], pathLength + 1, &pathLength);

    int32_t colorValue;
    napi_get_value_int32(env, args[3], &colorValue);

    setProperty<uint32_t>(env, ref, viewModelInstanceHandle, propertyPath.c_str(), static_cast<uint32_t>(colorValue),
                          &rive::CommandQueue::setViewModelInstanceColor);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 颜色属性获取
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppGetColorProperty
 */
napi_value CommandQueueGetColorProperty(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueGetColorProperty");
        return nullptr;
    }

    int64_t ref, requestID, viewModelInstanceHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);
    napi_get_value_int64(env, args[2], &viewModelInstanceHandle);

    size_t pathLength;
    napi_get_value_string_utf8(env, args[3], nullptr, 0, &pathLength);
    std::string propertyPath(pathLength + 1, '\0');
    napi_get_value_string_utf8(env, args[3], &propertyPath[0], pathLength + 1, &pathLength);

    getProperty(env, ref, requestID, viewModelInstanceHandle, propertyPath.c_str(),
                &rive::CommandQueue::requestViewModelInstanceColor);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 触发器属性触发
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppFireTriggerProperty
 */
napi_value CommandQueueFireTriggerProperty(napi_env env, napi_callback_info info)
{
    size_t argc = 3;
    napi_value args[3];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 3) {
        LOGE("Wrong number of arguments in CommandQueueFireTriggerProperty");
        return nullptr;
    }

    int64_t ref, viewModelInstanceHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &viewModelInstanceHandle);

    size_t pathLength;
    napi_get_value_string_utf8(env, args[2], nullptr, 0, &pathLength);
    std::string propertyPath(pathLength + 1, '\0');
    napi_get_value_string_utf8(env, args[2], &propertyPath[0], pathLength + 1, &pathLength);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto handle = handleFromLong<rive::ViewModelInstanceHandle>(viewModelInstanceHandle);
    commandQueue->fireViewModelTrigger(handle, propertyPath);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 属性订阅
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppSubscribeToProperty
 */
napi_value CommandQueueSubscribeToProperty(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueSubscribeToProperty");
        return nullptr;
    }

    int64_t ref, viewModelInstanceHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &viewModelInstanceHandle);

    size_t pathLength;
    napi_get_value_string_utf8(env, args[2], nullptr, 0, &pathLength);
    std::string propertyPath(pathLength + 1, '\0');
    napi_get_value_string_utf8(env, args[2], &propertyPath[0], pathLength + 1, &pathLength);

    int32_t propertyType;
    napi_get_value_int32(env, args[3], &propertyType);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto handle = handleFromLong<rive::ViewModelInstanceHandle>(viewModelInstanceHandle);
    auto dataType = static_cast<rive::DataType>(propertyType);

    commandQueue->subscribeToViewModelProperty(handle, propertyPath, dataType);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 属性取消订阅
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppUnsubscribeFromProperty
 */
napi_value CommandQueueUnsubscribeFromProperty(napi_env env, napi_callback_info info)
{
    size_t argc = 4;
    napi_value args[4];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 4) {
        LOGE("Wrong number of arguments in CommandQueueUnsubscribeFromProperty");
        return nullptr;
    }

    int64_t ref, viewModelInstanceHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &viewModelInstanceHandle);

    size_t pathLength;
    napi_get_value_string_utf8(env, args[2], nullptr, 0, &pathLength);
    std::string propertyPath(pathLength + 1, '\0');
    napi_get_value_string_utf8(env, args[2], &propertyPath[0], pathLength + 1, &pathLength);

    int32_t propertyType;
    napi_get_value_int32(env, args[3], &propertyType);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto handle = handleFromLong<rive::ViewModelInstanceHandle>(viewModelInstanceHandle);
    auto dataType = static_cast<rive::DataType>(propertyType);

    commandQueue->unsubscribeToViewModelProperty(handle, propertyPath, dataType);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 图像解码
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppDecodeImage
 */
napi_value CommandQueueDecodeImage(napi_env env, napi_callback_info info)
{
    size_t argc = 3;
    napi_value args[3];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 3) {
        LOGE("Wrong number of arguments in CommandQueueDecodeImage");
        return nullptr;
    }

    int64_t ref, requestID;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);

    void *arrayBufferData;
    size_t arrayBufferLength;
    napi_get_arraybuffer_info(env, args[2], &arrayBufferData, &arrayBufferLength);

    std::vector<uint8_t> byteVec(static_cast<uint8_t *>(arrayBufferData),
                                 static_cast<uint8_t *>(arrayBufferData) + arrayBufferLength);

    commandQueue->decodeImage(byteVec, nullptr, requestID);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 图像删除
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppDecodeImage
 */
napi_value CommandQueueDeleteImage(napi_env env, napi_callback_info info)
{
    size_t argc = 2;
    napi_value args[2];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 2) {
        LOGE("Wrong number of arguments in CommandQueueDeleteImage");
        return nullptr;
    }

    int64_t ref, imageHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &imageHandle);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto handle = handleFromLong<rive::RenderImageHandle>(imageHandle);
    commandQueue->deleteImage(handle);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 图像注册
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppRegisterImage
 */
napi_value CommandQueueRegisterImage(napi_env env, napi_callback_info info)
{
    size_t argc = 3;
    napi_value args[3];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 3) {
        LOGE("Wrong number of arguments in CommandQueueRegisterImage");
        return nullptr;
    }

    int64_t ref, imageHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[2], &imageHandle);

    size_t pathLength;
    napi_get_value_string_utf8(env, args[1], nullptr, 0, &pathLength);
    std::string path(pathLength + 1, '\0');
    napi_get_value_string_utf8(env, args[1], &path[0], pathLength + 1, &pathLength);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto handle = handleFromLong<rive::RenderImageHandle>(imageHandle);
    commandQueue->addGlobalImageAsset(path, handle);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 图像注销
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppUnregisterImage
 */
napi_value CommandQueueUnregisterImage(napi_env env, napi_callback_info info)
{
    size_t argc = 2;
    napi_value args[2];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 2) {
        LOGE("Wrong number of arguments in CommandQueueUnregisterImage");
        return nullptr;
    }

    int64_t ref;
    napi_get_value_int64(env, args[0], &ref);

    size_t pathLength;
    napi_get_value_string_utf8(env, args[1], nullptr, 0, &pathLength);
    std::string path(pathLength + 1, '\0');
    napi_get_value_string_utf8(env, args[1], &path[0], pathLength + 1, &pathLength);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    commandQueue->removeGlobalImageAsset(path);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 音频解码
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppDecodeAudio
 */
napi_value CommandQueueDecodeAudio(napi_env env, napi_callback_info info)
{
    size_t argc = 3;
    napi_value args[3];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 3) {
        LOGE("Wrong number of arguments in CommandQueueDecodeAudio");
        return nullptr;
    }

    int64_t ref, requestID;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);

    void *arrayBufferData;
    size_t arrayBufferLength;
    napi_get_arraybuffer_info(env, args[2], &arrayBufferData, &arrayBufferLength);

    std::vector<uint8_t> byteVec(static_cast<uint8_t *>(arrayBufferData),
                                 static_cast<uint8_t *>(arrayBufferData) + arrayBufferLength);

    commandQueue->decodeAudio(byteVec, nullptr, requestID);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 音频删除
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppDeleteAudio
 */
napi_value CommandQueueDeleteAudio(napi_env env, napi_callback_info info)
{
    size_t argc = 2;
    napi_value args[2];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 2) {
        LOGE("Wrong number of arguments in CommandQueueDeleteAudio");
        return nullptr;
    }

    int64_t ref, audioHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &audioHandle);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto handle = handleFromLong<rive::AudioSourceHandle>(audioHandle);
    commandQueue->deleteAudio(handle);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 音频注册
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppRegisterAudio
 */
napi_value CommandQueueRegisterAudio(napi_env env, napi_callback_info info)
{
    size_t argc = 3;
    napi_value args[3];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 3) {
        LOGE("Wrong number of arguments in CommandQueueRegisterAudio");
        return nullptr;
    }

    int64_t ref, audioHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[2], &audioHandle);

    size_t pathLength;
    napi_get_value_string_utf8(env, args[1], nullptr, 0, &pathLength);
    std::string path(pathLength + 1, '\0');
    napi_get_value_string_utf8(env, args[1], &path[0], pathLength + 1, &pathLength);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto handle = handleFromLong<rive::AudioSourceHandle>(audioHandle);
    commandQueue->addGlobalAudioAsset(path, handle);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 音频注销
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppUnregisterAudio
 */
napi_value CommandQueueUnregisterAudio(napi_env env, napi_callback_info info)
{
    size_t argc = 2;
    napi_value args[2];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 2) {
        LOGE("Wrong number of arguments in CommandQueueUnregisterAudio");
        return nullptr;
    }

    int64_t ref;
    napi_get_value_int64(env, args[0], &ref);

    size_t pathLength;
    napi_get_value_string_utf8(env, args[1], nullptr, 0, &pathLength);
    std::string path(pathLength + 1, '\0');
    napi_get_value_string_utf8(env, args[1], &path[0], pathLength + 1, &pathLength);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    commandQueue->removeGlobalAudioAsset(path);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 字体解码
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppDecodeFont
 */
napi_value CommandQueueDecodeFont(napi_env env, napi_callback_info info)
{
    size_t argc = 3;
    napi_value args[3];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 3) {
        LOGE("Wrong number of arguments in CommandQueueDecodeFont");
        return nullptr;
    }

    int64_t ref, requestID;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &requestID);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);

    void *arrayBufferData;
    size_t arrayBufferLength;
    napi_get_arraybuffer_info(env, args[2], &arrayBufferData, &arrayBufferLength);

    std::vector<uint8_t> byteVec(static_cast<uint8_t *>(arrayBufferData),
                                 static_cast<uint8_t *>(arrayBufferData) + arrayBufferLength);

    auto fontHandle = commandQueue->decodeFont(byteVec, nullptr, requestID);

    napi_value result;
    napi_create_int64(env, longFromHandle(fontHandle), &result);
    return result;
}

/**
 * CommandQueue 字体删除
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppDeleteFont
 */
napi_value CommandQueueDeleteFont(napi_env env, napi_callback_info info)
{
    size_t argc = 2;
    napi_value args[2];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 2) {
        LOGE("Wrong number of arguments in CommandQueueDeleteFont");
        return nullptr;
    }

    int64_t ref, fontHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &fontHandle);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto handle = handleFromLong<rive::FontHandle>(fontHandle);
    commandQueue->deleteFont(handle);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 字体注册
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppRegisterFont
 */
napi_value CommandQueueRegisterFont(napi_env env, napi_callback_info info)
{
    size_t argc = 3;
    napi_value args[3];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 3) {
        LOGE("Wrong number of arguments in CommandQueueRegisterFont");
        return nullptr;
    }

    int64_t ref, fontHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[2], &fontHandle);

    size_t pathLength;
    napi_get_value_string_utf8(env, args[1], nullptr, 0, &pathLength);
    std::string path(pathLength + 1, '\0');
    napi_get_value_string_utf8(env, args[1], &path[0], pathLength + 1, &pathLength);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto handle = handleFromLong<rive::FontHandle>(fontHandle);
    commandQueue->addGlobalFontAsset(path, handle);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 字体注销
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppUnregisterFont
 */
napi_value CommandQueueUnregisterFont(napi_env env, napi_callback_info info)
{
    size_t argc = 2;
    napi_value args[2];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 2) {
        LOGE("Wrong number of arguments in CommandQueueUnregisterFont");
        return nullptr;
    }

    int64_t ref;
    napi_get_value_int64(env, args[0], &ref);

    size_t pathLength;
    napi_get_value_string_utf8(env, args[1], nullptr, 0, &pathLength);
    std::string path(pathLength + 1, '\0');
    napi_get_value_string_utf8(env, args[1], &path[0], pathLength + 1, &pathLength);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    commandQueue->removeGlobalFontAsset(path);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 指针移动事件
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppPointerMove
 */
napi_value CommandQueuePointerMove(napi_env env, napi_callback_info info)
{
    size_t argc = 9;
    napi_value args[9];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 9) {
        LOGE("Wrong number of arguments in CommandQueuePointerMove");
        return nullptr;
    }

    int64_t ref, stateMachineHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &stateMachineHandle);

    int32_t fit, align, pointerID;
    napi_get_value_int32(env, args[2], &fit);
    napi_get_value_int32(env, args[3], &align);
    napi_get_value_int32(env, args[6], &pointerID);

    double surfaceWidth, surfaceHeight, pointerX, pointerY;
    napi_get_value_double(env, args[4], &surfaceWidth);
    napi_get_value_double(env, args[5], &surfaceHeight);
    napi_get_value_double(env, args[7], &pointerX);
    napi_get_value_double(env, args[8], &pointerY);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    rive::CommandQueue::PointerEvent event{
        .fit = GetFit(env, args[2]),
        .alignment = GetAlignment(env, args[3]),
        .screenBounds = rive::Vec2D(static_cast<float_t>(surfaceWidth), static_cast<float_t>(surfaceHeight)),
        .position = rive::Vec2D(static_cast<float_t>(pointerX), static_cast<float_t>(pointerY))};
    event.pointerId = pointerID;

    commandQueue->pointerMove(handleFromLong<rive::StateMachineHandle>(stateMachineHandle), event);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 指针按下事件
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppPointerDown
 */
napi_value CommandQueuePointerDown(napi_env env, napi_callback_info info)
{
    size_t argc = 9;
    napi_value args[9];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 9) {
        LOGE("Wrong number of arguments in CommandQueuePointerDown");
        return nullptr;
    }

    int64_t ref, stateMachineHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &stateMachineHandle);

    int32_t fit, alignment, pointerID;
    napi_get_value_int32(env, args[2], &fit);
    napi_get_value_int32(env, args[3], &alignment);
    napi_get_value_int32(env, args[6], &pointerID);

    double surfaceWidth, surfaceHeight, pointerX, pointerY;
    napi_get_value_double(env, args[4], &surfaceWidth);
    napi_get_value_double(env, args[5], &surfaceHeight);
    napi_get_value_double(env, args[7], &pointerX);
    napi_get_value_double(env, args[8], &pointerY);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    rive::CommandQueue::PointerEvent event{
        .fit = GetFit(env, args[2]),
        .alignment = GetAlignment(env, args[3]),
        .screenBounds = rive::Vec2D(static_cast<float_t>(surfaceWidth), static_cast<float_t>(surfaceHeight)),
        .position = rive::Vec2D(static_cast<float_t>(pointerX), static_cast<float_t>(pointerY))};
    event.pointerId = pointerID;

    commandQueue->pointerDown(handleFromLong<rive::StateMachineHandle>(stateMachineHandle), event);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 指针抬起事件
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppPointerUp
 */
napi_value CommandQueuePointerUp(napi_env env, napi_callback_info info)
{
    size_t argc = 9;
    napi_value args[9];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 9) {
        LOGE("Wrong number of arguments in CommandQueuePointerUp");
        return nullptr;
    }

    int64_t ref, stateMachineHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &stateMachineHandle);

    int32_t fit, alignment, pointerID;
    napi_get_value_int32(env, args[2], &fit);
    napi_get_value_int32(env, args[3], &alignment);
    napi_get_value_int32(env, args[6], &pointerID);

    double surfaceWidth, surfaceHeight, pointerX, pointerY;
    napi_get_value_double(env, args[4], &surfaceWidth);
    napi_get_value_double(env, args[5], &surfaceHeight);
    napi_get_value_double(env, args[7], &pointerX);
    napi_get_value_double(env, args[8], &pointerY);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    rive::CommandQueue::PointerEvent event{
        .fit = GetFit(env, args[2]),
        .alignment = GetAlignment(env, args[3]),
        .screenBounds = rive::Vec2D(static_cast<float_t>(surfaceWidth), static_cast<float_t>(surfaceHeight)),
        .position = rive::Vec2D(static_cast<float_t>(pointerX), static_cast<float_t>(pointerY))};
    event.pointerId = pointerID;

    commandQueue->pointerUp(handleFromLong<rive::StateMachineHandle>(stateMachineHandle), event);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 指针退出事件
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppPointerExit
 */
napi_value CommandQueuePointerExit(napi_env env, napi_callback_info info)
{
    size_t argc = 9;
    napi_value args[9];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 9) {
        LOGE("Wrong number of arguments in CommandQueuePointerExit");
        return nullptr;
    }

    int64_t ref, stateMachineHandle;
    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &stateMachineHandle);

    int32_t fit, alignment, pointerID;
    napi_get_value_int32(env, args[2], &fit);
    napi_get_value_int32(env, args[3], &alignment);
    napi_get_value_int32(env, args[6], &pointerID);

    double surfaceWidth, surfaceHeight, pointerX, pointerY;
    napi_get_value_double(env, args[4], &surfaceWidth);
    napi_get_value_double(env, args[5], &surfaceHeight);
    napi_get_value_double(env, args[7], &pointerX);
    napi_get_value_double(env, args[8], &pointerY);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    rive::CommandQueue::PointerEvent event{
        .fit = GetFit(env, args[2]),
        .alignment = GetAlignment(env, args[3]),
        .screenBounds = rive::Vec2D(static_cast<float_t>(surfaceWidth), static_cast<float_t>(surfaceHeight)),
        .position = rive::Vec2D(static_cast<float_t>(pointerX), static_cast<float_t>(pointerY))};
    event.pointerId = pointerID;

    commandQueue->pointerExit(handleFromLong<rive::StateMachineHandle>(stateMachineHandle), event);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 创建绘制键
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppCreateDrawKey
 */
napi_value CommandQueueCreateDrawKey(napi_env env, napi_callback_info info)
{
    size_t argc = 1;
    napi_value args[1];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 1) {
        LOGE("Wrong number of arguments in CommandQueueCreateDrawKey");
        return nullptr;
    }

    int64_t ref;
    napi_get_value_int64(env, args[0], &ref);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto drawKey = commandQueue->createDrawKey();

    napi_value result;
    napi_create_int64(env, longFromHandle(drawKey), &result);
    return result;
}

/**
 * CommandQueue 轮询消息
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppPollMessages
 */
napi_value CommandQueuePollMessages(napi_env env, napi_callback_info info)
{
    size_t argc = 1;
    napi_value args[1];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 1) {
        LOGE("Wrong number of arguments in CommandQueuePollMessages");
        return nullptr;
    }

    int64_t ref;
    napi_get_value_int64(env, args[0], &ref);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    commandQueue->processMessages();

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 绘制函数
 * 对应原 JNI Java_app_rive_core_CommandQueue_cppDraw
 */
napi_value CommandQueueDraw(napi_env env, napi_callback_info info)
{
    size_t argc = 13;
    napi_value args[13];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 13) {
        LOGE("Wrong number of arguments in CommandQueueDraw");
        return nullptr;
    }

    int64_t ref, eglDisplayRef, eglSurfaceRef, eglContextRef, drawKey;
    int64_t artboardHandleRef, stateMachineHandleRef, renderTargetRef;
    int32_t width, height, ohosClearColor;

    napi_get_value_int64(env, args[0], &ref);
    napi_get_value_int64(env, args[1], &eglDisplayRef);
    napi_get_value_int64(env, args[2], &eglSurfaceRef);
    napi_get_value_int64(env, args[3], &eglContextRef);
    napi_get_value_int64(env, args[4], &drawKey);
    napi_get_value_int64(env, args[5], &artboardHandleRef);
    napi_get_value_int64(env, args[6], &stateMachineHandleRef);
    napi_get_value_int64(env, args[7], &renderTargetRef);
    napi_get_value_int32(env, args[8], &width);
    napi_get_value_int32(env, args[9], &height);
    napi_get_value_int32(env, args[12], &ohosClearColor);

    // 获取fit和alignment参数
    rive::Fit fit = rive::Fit::none;
    rive::Alignment alignment = rive::Alignment::center;

    // 从JavaScript对象中提取fit和alignment值
    napi_value fitValue, alignmentValue;
    napi_get_named_property(env, args[10], "value", &fitValue);
    napi_get_named_property(env, args[11], "value", &alignmentValue);

    int32_t fitInt, alignmentInt;
    napi_get_value_int32(env, fitValue, &fitInt);
    napi_get_value_int32(env, alignmentValue, &alignmentInt);

    fit = GetFit(env, args[10]);
    alignment = GetAlignment(env, args[11]);
    auto clearColor = static_cast<uint32_t>(ohosClearColor);

    auto commandQueue = reinterpret_cast<rive::CommandQueue *>(ref);
    auto eglDisplay = reinterpret_cast<EGLDisplay>(eglDisplayRef);
    auto eglSurface = reinterpret_cast<EGLSurface>(eglSurfaceRef);
    auto eglContext = reinterpret_cast<EGLContext>(eglContextRef);
    auto renderTarget = reinterpret_cast<rive::gpu::RenderTargetGL *>(renderTargetRef);

    auto loop = [eglDisplay, eglSurface, eglContext, artboardHandleRef, stateMachineHandleRef, renderTarget, width,
                 height, fit, alignment, clearColor](rive::DrawKey, rive::CommandServer *server) {
        auto artboard = server->getArtboardInstance(handleFromLong<rive::ArtboardHandle>(artboardHandleRef));
        if (artboard == nullptr) {
            return;
        }

        auto stateMachine =
            server->getStateMachineInstance(handleFromLong<rive::StateMachineHandle>(stateMachineHandleRef));
        if (stateMachine == nullptr) {
            return;
        }

        // Make the EGL surface current
        eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);

        auto error = eglGetError();
        if (error != EGL_SUCCESS) {
            LOGE("EGL error setting context (SetSurface): %d", error);
            return;
        }

        // Stack allocate a Rive Renderer
        auto riveContext = static_cast<rive::gpu::RenderContext *>(server->factory());

        riveContext->beginFrame(rive::gpu::RenderContext::FrameDescriptor{
            .renderTargetWidth = static_cast<uint32_t>(width),
            .renderTargetHeight = static_cast<uint32_t>(height),
            .loadAction = rive::gpu::LoadAction::clear,
            .clearColor = clearColor,
        });

        auto renderer = rive::RiveRenderer(riveContext);

        // Draw the .riv
        renderer.align(fit, alignment,
                       rive::AABB(0.0f, 0.0f, static_cast<float_t>(width), static_cast<float_t>(height)),
                       artboard->bounds());
        artboard->draw(&renderer);

        // Flush the draw commands
        riveContext->flush({
            .renderTarget = renderTarget,
        });

        // Swap buffers
        eglSwapBuffers(eglDisplay, eglSurface);
    };

    commandQueue->draw(handleFromLong<rive::DrawKey>(drawKey), loop);

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 渲染目标删除
 * 对应原 JNI Java_app_rive_core_RiveSurface_cppDelete
 */
napi_value CommandQueueDeleteRiveSurface(napi_env env, napi_callback_info info)
{
    size_t argc = 1;
    napi_value args[1];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 1) {
        LOGE("Wrong number of arguments in CommandQueueDeleteRiveSurface");
        return nullptr;
    }

    int64_t renderTargetRef;
    napi_get_value_int64(env, args[0], &renderTargetRef);

    auto renderTarget = reinterpret_cast<rive::gpu::RenderTargetGL *>(renderTargetRef);
    delete renderTarget;

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}

/**
 * CommandQueue 删除监听器
 * 对应原 JNI Java_app_rive_core_Listeners_cppDelete
 */
napi_value CommandQueueDeleteListeners(napi_env env, napi_callback_info info)
{
    size_t argc = 7;
    napi_value args[7];

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    if (argc < 7) {
        LOGE("Wrong number of arguments in Napi_CommandQueue_cppDeleteListeners");
        return nullptr;
    }

    int64_t fileListenerRef, artboardListenerRef, stateMachineListenerRef;
    int64_t viewModelInstanceListenerRef, imageListenerRef, audioListenerRef, fontListenerRef;

    napi_get_value_int64(env, args[0], &fileListenerRef);
    napi_get_value_int64(env, args[1], &artboardListenerRef);
    napi_get_value_int64(env, args[2], &stateMachineListenerRef);
    napi_get_value_int64(env, args[3], &viewModelInstanceListenerRef);
    napi_get_value_int64(env, args[4], &imageListenerRef);
    napi_get_value_int64(env, args[5], &audioListenerRef);
    napi_get_value_int64(env, args[6], &fontListenerRef);

    auto fileListener = reinterpret_cast<FileListener *>(fileListenerRef);
    auto artboardListener = reinterpret_cast<ArtboardListener *>(artboardListenerRef);
    auto stateMachineListener = reinterpret_cast<StateMachineListener *>(stateMachineListenerRef);
    auto viewModelInstanceListener = reinterpret_cast<ViewModelInstanceListener *>(viewModelInstanceListenerRef);
    auto imageListener = reinterpret_cast<ImageListener *>(imageListenerRef);
    auto audioListener = reinterpret_cast<AudioListener *>(audioListenerRef);
    auto fontListener = reinterpret_cast<FontListener *>(fontListenerRef);

    delete fileListener;
    delete artboardListener;
    delete stateMachineListener;
    delete viewModelInstanceListener;
    delete imageListener;
    delete audioListener;
    delete fontListener;

    napi_value undefined;
    napi_get_undefined(env, &undefined);
    return undefined;
}
} // namespace ohos_rive